<template>

  <div>

    <div class="component-panel">

      <div>
        <div>公共配置</div>
        <div>私有配置</div>
      </div>
      <div>
        <div class="public-config"></div>
        <div class="private-config"></div>

      </div>


    <div class="component-title-bar">
      <span>组件公共配置</span>
    </div>
    <div class="component-body">
      <el-form  @submit.prevent label-position="top">
          <el-form-item label="页面名称">
              <el-input v-model="props.component.title" />
          </el-form-item>

          <el-row :gutter="8" style="margin-bottom: 12px;">
            <el-col :span="12">
              <el-form-item label="宽度">
                <el-input-number v-model="props.component.width" :min="0" :max="90000" controls-position="right"/>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="高度">
                <el-input-number v-model="props.component.height" :min="0" :max="90000" controls-position="right"/>
              </el-form-item>
            </el-col>
          </el-row>

          <el-row :gutter="8" style="margin-bottom: 12px;">
            <el-col :span="12">
              <el-form-item label="位置X">
                <el-input-number v-model="props.component.x" :min="0" :max="90000" controls-position="right"/>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="位置Y">
                <el-input-number v-model="props.component.y" :min="0" :max="90000" controls-position="right"/>
              </el-form-item>
            </el-col>
          </el-row>

          <el-form-item label="背景颜色">
              <el-color-picker v-model="props.component.bgColor"  />
          </el-form-item>
      </el-form>
    </div>
    </div>

    <div class="component-title-bar" style="margin-top: 4px;">
      <span>组件私有配置</span>
    </div>
    <div class="component-body">
      <el-tabs>
        <el-tab-pane label="属性" v-if="attributes.length">
          <div class="attribute-class" v-for="attribute in attributes" :key="attribute.identifier" :label="attribute.name"> 
            <el-scrollbar height="calc(100vh - 712px)">
              <el-form  @submit.prevent labelWidth="70" label-position="top">
                <div v-for=" field in attribute.fields" style="overflow: hidden;">
                  <Vector2DField v-if="field.dataType.type=='v2' && field.display==true " :identifier="field.identifier" :pidentifier="attribute.identifier" :label="field.name" :value="field.dataType.value" :required="field.required"  @onchange="onchange"  />
                  <EnumField v-if="field.dataType.type=='enum' && field.display==true " :identifier="field.identifier" :pidentifier="attribute.identifier"  :label="field.name" :options="field.dataType.specs" :value="field.dataType.value" :required="field.required"  @onchange="onchange"  />
                  <Vector4DField v-if="field.dataType.type=='v4' && field.display==true " :identifier="field.identifier" :pidentifier="attribute.identifier"  :label="field.name" :value="field.dataType.value" :required="field.required"  @onchange="onchange"  />
                 
                 
                  <BooleanField v-if="field.dataType.type=='boolean' && field.display==true " :identifier="field.identifier" :pidentifier="attribute.identifier"  :label="field.name" :options="field.dataType.specs" :value="field.dataType.value" :required="field.required"  @onchange="onchange"  />
                  <ColorField v-if="field.dataType.type=='color' && field.display==true " :identifier="field.identifier" :pidentifier="attribute.identifier"  :label="field.name" :value="field.dataType.value" :required="field.required" @onchange="onchange" />
                 
            
                  <StringField v-if="field.dataType.type=='string' && field.display==true " :identifier="field.identifier" :pidentifier="attribute.identifier"  :label="field.name" :length="field.dataType.specs.length" :value="String(field.dataType.value || '')" :required="field.required" :readonly="field.readonly" @onchange="onchange" />
                  <NumberField v-if="field.dataType.type=='float' && field.display==true " :identifier="field.identifier" :pidentifier="attribute.identifier"  :label="field.name" :min="field.dataType.specs.min" :max="field.dataType.specs.max" :step="field.dataType.specs.step" :value="field.dataType.value" :required="field.required" @onchange="onchange"/>
                  <NumberField v-if="field.dataType.type=='int' && field.display==true " :identifier="field.identifier" :pidentifier="attribute.identifier"  :label="field.name" :min="field.dataType.specs.min" :max="field.dataType.specs.max" :step="field.dataType.specs.step" :value="field.dataType.value" :required="field.required" @onchange="onchange"/>
                  <NumberField v-if="field.dataType.type=='double' && field.display==true " :identifier="field.identifier" :pidentifier="attribute.identifier"  :label="field.name" :min="field.dataType.specs.min" :max="field.dataType.specs.max" :step="field.dataType.specs.step" :value="field.dataType.value" :required="field.required" @onchange="onchange"/>
                  <StructField v-if="field.dataType.type=='struct' && field.display==true" :baseUrl="BASE_API" :pidentifier="attribute.identifier" :list="field.dataType.specs" :name="field.name"  @onchange="onchange"/>                  
                  <ImgField v-if="field.dataType.type=='img' && field.display==true " :baseUrl="BASE_API" :identifier="field.identifier" :pidentifier="attribute.identifier" :label="field.name" :value="field.dataType.value" :required="field.required"  @onchange="onchange"  />
                   
                  <CssField
                    v-if="field.dataType.type=='css' && field.display==true"
                    :identifier="field.identifier"
                    :pidentifier="attribute.identifier"
                    :label="field.name"
                    :value="field.dataType.value"
                    :required="field.required"
                    @onchange="onchange"
                  />
                </div>
              </el-form>
            </el-scrollbar>
          </div>
        </el-tab-pane>
        <el-tab-pane label="方法" v-if="methods.length">
          <el-table :data="methods">
            <el-table-column prop="name" label="方法名" />
            <el-table-column prop="inputData" label="参数">
              <template #default="{ row }">
                <span v-if="Array.isArray(row.inputData)">
                  <span v-for="param in row.inputData" :key="param.identifier">
                    {{ param.name }}({{ param.dataType?.type }})
                  </span>
                </span>
                <span v-else>{{ row.inputData }}</span>
              </template>
            </el-table-column>
            <el-table-column prop="description" label="说明" />
          </el-table>
        </el-tab-pane>
        <el-tab-pane label="事件" v-if="events.length">
          <el-table :data="events">
            <el-table-column prop="name" label="事件名" />
            <el-table-column prop="inputData" label="参数">
              <template #default="{ row }">
                <span v-if="Array.isArray(row.inputData)">
                  <span v-for="param in row.inputData" :key="param.identifier">
                    {{ param.name }}({{ param.dataType?.type }})
                  </span>
                </span>
                <span v-else>{{ row.inputData }}</span>
              </template>
            </el-table-column>
            <el-table-column prop="description" label="说明" />
          </el-table>
        </el-tab-pane>
      </el-tabs>


    </div>
  </div>
  
</template>

<script setup lang="ts">
import { ref, watch } from 'vue'
import { getActorParam} from '@/utils/visual/ConfigUtil'
import EnumField from "@/components/FormField/EnumField.vue";
import Vector2DField from "@/components/FormField/Vector2DField.vue";
import Vector4DField from "@/components/FormField/Vector4DField.vue";
import BooleanField from "@/components/FormField/BooleanField.vue";
import ColorField from "@/components/FormField/ColorField.vue";
import StringField from "@/components/FormField/StringField.vue";
import NumberField from "@/components/FormField/NumberField.vue";
import StructField from "@/components/FormField/StructField.vue";
import ImgField from "@/components/FormField/ImgField.vue";
import CssField from '@/components/FormField/CssField.vue';
import { ComponentLibraryService } from '@/api/visual/componentLibraryApi'
import { axiosInstance } from '@/utils/http/index'
import { ComponentInstance } from '@/types/visual-app';
import { useComponentDataModelStore } from '@/store/modules/component'
const BASE_API = axiosInstance.defaults.baseURL
const props = defineProps<{ component: ComponentInstance }>()

const emit = defineEmits(['config-change'])
const attributes = ref<any[]>([])
const methods = ref<any[]>([])
const events = ref<any[]>([])
let attributeParams:any={};

const componentDataModel = ref<any[]>([]);
const componentDataModelStore = useComponentDataModelStore();
const getComponentDataModel = async (componentId: string) => {
  const cached = componentDataModelStore.getDataModel(componentId);
  if (cached) {
    componentDataModel.value = cached;
    return componentDataModel.value;
  }
  const data = await ComponentLibraryService.getComponentDataModelList(componentId);
  componentDataModel.value = data || [];
  componentDataModelStore.setDataModel(componentId, componentDataModel.value);
  return componentDataModel.value;
}

watch(() => props.component, async (val) => {
  await getComponentDataModel(val.componentId);
  attributes.value = []
  attributeParams={}

  // if (!props.component.config) {
  //   props.component.config = {};
  // }


  if (Array.isArray(componentDataModel.value)) {
    for (const item of componentDataModel.value) {
      if (item.type === 'attribute' && item.hasOwnProperty('inputData')) {
        try {

          // if (!props.component.config.attributes) {
          //     props.component.config.attributes = { };
          // }

          const inputData = typeof item.inputData === 'string' ? JSON.parse(item.inputData) : item.inputData
          if (Array.isArray(inputData)) {
            const attributeConfig=props.component['config']['attributes'];
            if(attributeConfig && attributeConfig.hasOwnProperty(item.identifier)){
              attributeParams[item.identifier]=getActorParam({},attributeConfig[item.identifier],inputData,undefined,true);
            }else{
              attributeParams[item.identifier]=getActorParam({},{},inputData,undefined,true);
            }

            //props.component.config.attributes[item.identifier]=attributeParams[item.identifier];

            attributes.value.push({
              name:item.name,
              identifier:item.identifier,
              fields:inputData
            });
          }
        } catch {}
      }
      if (item.type === 'method' && item.inputData) {
        try {
          const inputData = typeof item.inputData === 'string' ? JSON.parse(item.inputData) : item.inputData
          methods.value.push({ ...item, inputData })
        } catch {}
      }
      if (item.type === 'event' && item.inputData) {
        try {
          const inputData = typeof item.inputData === 'string' ? JSON.parse(item.inputData) : item.inputData
          events.value.push({ ...item, inputData })
        } catch {}
      }
    }
  }
}, { immediate: true })

// 递归合并函数，保证所有对象类型的key都只做内容合并
function deepAssign(target: any, source: any) {
  Object.keys(source).forEach(key => {
    if (
      typeof source[key] === 'object' &&
      source[key] !== null &&
      typeof target[key] === 'object' &&
      target[key] !== null
    ) {
      deepAssign(target[key], source[key]);
    } else {
      target[key] = source[key];
    }
  });
}

const onchange = (input: { pidentifier: string, identifier: string, value: any }) => {
  if (input.pidentifier) {
    let pids = input.pidentifier.split(".");
    let pdata = attributeParams;
    for (let p of pids) {
      if (pdata.hasOwnProperty(p)) {
        pdata = pdata[p];
      }
    }
    if (pdata.hasOwnProperty(input.identifier)) {
      pdata[input.identifier] = input.value;
    }
  } else {
    if (attributeParams.hasOwnProperty(input.identifier)) {
      attributeParams[input.identifier] = input.value;
    }
  }

  if (props.component) {
    if (!props.component.config) {
      props.component.config = { attributes: {} };
    }
    if (!props.component.config.attributes) {
      props.component.config.attributes = {};
    }
    // 递归合并，保证所有对象类型的key都只做内容合并
    deepAssign(props.component.config.attributes, attributeParams);
    emit('config-change', props.component);
  }
}



</script> 

<style scoped>
.component-panel{
  border: 0px solid var(--art-card-border);
  padding: 0px;
  background-color: var(--art-main-bg-color);
  overflow: hidden;
}

.component-title-bar {
  height: 36px;
  background: linear-gradient(90deg, #5d87ffb5 0%, #1e90ff4f 100%);
  line-height: 36px;
  border-left: 0px solid #5d87ff;
  padding-left: 16px;
  color: #fff;
  font-weight: bold;
  font-size: 16px;
  /* box-shadow: 0 2px 8px #0002; */
  letter-spacing: 1px;
  /* margin-bottom: 10px; */
  position: relative;
  z-index: 1;
}

.component-body{
  padding: 8px;
  /* box-shadow: 0 1px 8px #5d87ff; */
  border: 1px solid var(--art-card-border);
}

.attribute-class > div {
  margin-bottom: 14px;
  padding: 10px 0;
  border-bottom: 1px dashed #3a3f4b;
}

.attribute-class > div:last-child {
  border-bottom: none;
}

.attribute-class label,
.attribute-class .title {
  font-weight: 600;
  color: #fff;
  font-size: 13px;
  margin-bottom: 6px;
  display: block;
  width: 150px;
}

.attribute-class .row-item{
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-content: flex-start;
  align-items: flex-start;
  margin-bottom: 5px;
  /* border-top: 1px solid #333333; */
  padding: 0px 8px 0px 8px;
}

.attribute-class .el-input,
.attribute-class .el-input-number,
.attribute-class .el-select,
.attribute-class .el-switch,
.attribute-class .el-date-picker {
  width: 220px;
  background: #1a1d23;
  /* border-radius: 4px; */
  color: #fff;
}

.attribute-class .el-input__inner,
.attribute-class .el-input-number__inner {
  background: #1a1d23;
  color: #fff;
  border: 1px solid #353a45;
}

.attribute-class .el-input__inner:focus,
.attribute-class .el-input-number__inner:focus {
  border-color: #409eff;
  box-shadow: 0 0 0 2px #409eff33;
}

.attribute-class .el-switch__core {
  background: #353a45;
}

.attribute-class .el-switch.is-checked .el-switch__core {
  background: #409eff;
}
</style>